package com.minelx.datamicroscope.querylanguage.data.render;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.minelx.datamicroscope.querylanguage.data.CollectingField;

import java.util.ArrayList;
import java.util.List;

import static java.util.stream.Collectors.toList;

public class Projection {
	private List<String> groupByResourceNames;

	private final List<String> projectionRetainedResourceNames;

	private final List<CollectingField> aggregations;

	private boolean isGroupByNeeded;

	public Projection() {
		projectionRetainedResourceNames = new ArrayList<>();
		aggregations = new ArrayList<>();
		isGroupByNeeded = false;
	}

	public void retains(String which) {
		projectionRetainedResourceNames.add(which);
	}

	public void addAggregationField(CollectingField collectingField) {
		aggregations.add(collectingField);
	}

	public void groupBy(List<String> groupByResourceNames) {
		isGroupByNeeded = true;
		this.groupByResourceNames = groupByResourceNames;
	}

	public JSONArray renderProjection() {
		JSONArray result = new JSONArray();
		// add grouping by segment if needed
		if (isGroupByNeeded) {
			result.add(renderGroupingBy());
		}
		result.add(renderRetains());
		return result;
	}

	private JSONObject renderRetains() {
		JSONObject result = new JSONObject();
		result.put("method", "retains");
		result.put("retained", projectionRetainedResourceNames);
		return result;
	}

	private JSONObject renderGroupingBy() {
		JSONObject result = new JSONObject();
		result.put("method", "aggregate");
		result.put("groupBy", groupByResourceNames);
		result.put("specs", new JSONArray(aggregations.stream()
				.map(CollectingField::renderAggregationSpec)
				.collect(toList())));
		return result;
	}
}
